package com.weilive.core.utils;

import java.io.ByteArrayInputStream;
import java.io.InputStream;
import java.io.StringReader;
import java.util.HashMap;
import java.util.Map;
import java.util.Map.Entry;

import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;
import javax.xml.xpath.XPath;
import javax.xml.xpath.XPathFactory;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.w3c.dom.Document;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
import org.xml.sax.InputSource;

public class XPathHelper {

	private final static Logger logger = LoggerFactory.getLogger(XPathHelper.class);

	private static DocumentBuilderFactory builderFactory = DocumentBuilderFactory.newInstance();

	private static DocumentBuilder builder = null;

	static {
		try {
			builder = builderFactory.newDocumentBuilder();
		} catch (ParserConfigurationException e) {
			logger.error(e.getMessage(), e);
		}
	}

	public static String getNodeValue(String sourceXml, String xpath) {
		if (builder != null) {
			try {
				InputSource is = new InputSource(new StringReader(sourceXml));
				Document xmlDocument = builder.parse(is);

				XPathFactory xpathFactory = XPathFactory.newInstance();
				XPath xpathObj = xpathFactory.newXPath();
				return xpathObj.evaluate(xpath, xmlDocument);
			} catch (Exception e) {
				e.printStackTrace();
			}

		}
		return null;
	}

	// map转化为xml
	public static String toXmlNode(Map<String, String> map) {

		StringBuilder sb = new StringBuilder();

		sb.append("<xml>");

		for (Entry<String, String> entry : map.entrySet()) {
			if (entry.getValue() != null && !entry.getValue().equals("")) {
				sb.append("<").append(entry.getKey()).append("><![CDATA[").append(entry.getValue()).append("]]></")
						.append(entry.getKey()).append(">");
			}
		}
		sb.append("</xml>");

		return sb.toString();
	}

	public static void main(String[] args) throws Exception {
		Map<String, String> toMap = new HashMap<String, String>();
		toMap.put("return_code", "FAIL");
		toMap.put("return_msg", "server error!");

		String toXml = XPathHelper.toXmlNode(toMap);

		System.out.println(toXml);

		Map<String, String> map = toMap(toXml);

		System.out.println(map);

		// xpathObj.evaluate(xpath, xmlDocument);
	}

	public static Map<String, String> toMap(String xml) throws Exception {
		if (xml == null || xml.equals("")) {
			return null;
		}
		InputStream is = new ByteArrayInputStream(xml.getBytes());
		DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
		dbf.setNamespaceAware(true);
		DocumentBuilder db = dbf.newDocumentBuilder();
		Document document = db.parse(is);
		return createMap(document.getDocumentElement());
	}

	private static Map<String, String> createMap(Node node) {
		Map<String, String> map = new HashMap<String, String>();
		NodeList nodeList = node.getChildNodes();
		for (int i = 0; i < nodeList.getLength(); i++) {
			Node currentNode = nodeList.item(i);
			if (currentNode.hasAttributes()) {
				for (int j = 0; j < currentNode.getAttributes().getLength(); j++) {
					Node item = currentNode.getAttributes().item(i);
					map.put(item.getNodeName(), item.getTextContent());
				}
			}
			if (node.getFirstChild() != null && node.getFirstChild().getNodeType() == Node.ELEMENT_NODE) {
				map.putAll(createMap(currentNode));
			} else if (node.getFirstChild().getNodeType() == Node.TEXT_NODE
					|| node.getFirstChild().getNodeType() == Node.CDATA_SECTION_NODE) {
				map.put(node.getLocalName(), node.getTextContent());
			}
		}
		return map;
	}
}
